home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / Filezilla Server / FileZilla_Server-0_9_41.exe / source / TransferSocket.cpp < prev    next >
C/C++ Source or Header  |  2012-02-20  |  30KB  |  1,234 lines

  1. // FileZilla Server - a Windows ftp server
  2.  
  3. // Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
  4.  
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9.  
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. // TransferSocket.cpp: Implementierungsdatei
  20. //
  21.  
  22. #include "stdafx.h"
  23. #include "TransferSocket.h"
  24. #include "ControlSocket.h"
  25. #include "options.h"
  26. #include "ServerThread.h"
  27. #include "AsyncGssSocketLayer.h"
  28. #include "AsyncSslSocketLayer.h"
  29. #include "Permissions.h"
  30. #include "iputils.h"
  31.  
  32. #ifdef _DEBUG
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36.  
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CTransferSocket
  39. CTransferSocket::CTransferSocket(CControlSocket *pOwner)
  40. : m_pSslLayer()
  41. , m_sslContext()
  42. {
  43.     ASSERT(pOwner);
  44.     m_pOwner = pOwner;
  45.     m_status = 0;
  46.     m_nMode = TRANSFERMODE_NOTSET;
  47.  
  48.     m_nBufferPos = NULL;
  49.     m_pBuffer = NULL;
  50.     m_pDirListing = NULL;
  51.     m_bAccepted = FALSE;
  52.  
  53.     m_bSentClose = FALSE;
  54.  
  55.     m_bReady = FALSE;
  56.     m_bStarted = FALSE;
  57.     GetSystemTime(&m_LastActiveTime);
  58.     m_wasActiveSinceCheck = false;
  59.     m_nRest = 0;
  60.  
  61.     m_pGssLayer = 0;
  62.  
  63.     m_hFile = INVALID_HANDLE_VALUE;
  64.  
  65.     m_nBufSize = (int)m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_BUFFERSIZE);
  66.  
  67.     m_useZlib = false;
  68.     memset(&m_zlibStream, 0, sizeof(m_zlibStream));
  69.  
  70.     m_zlibBytesIn = 0;
  71.     m_zlibBytesOut = 0;
  72.  
  73.     m_pBuffer2 = 0;
  74.     
  75.     m_currentFileOffset = 0;
  76.  
  77.     m_waitingForSslHandshake = false;
  78.  
  79.     m_premature_send = false;
  80. }
  81.  
  82. void CTransferSocket::Init(t_dirlisting *pDir, int nMode)
  83. {
  84.     ASSERT(nMode==TRANSFERMODE_LIST || nMode==TRANSFERMODE_NLST);
  85.     ASSERT(pDir);
  86.     m_bReady = TRUE;
  87.     m_status = 0;
  88.     if (m_pBuffer)
  89.         delete [] m_pBuffer;
  90.     m_pBuffer = 0;
  91.     if (m_pBuffer2)
  92.         delete [] m_pBuffer2;
  93.     m_pBuffer2 = 0;
  94.     
  95.     m_pDirListing = pDir;
  96.  
  97.     m_nMode = nMode;
  98.  
  99.     if (m_hFile != INVALID_HANDLE_VALUE)
  100.         CloseHandle(m_hFile);
  101.     m_nBufferPos = 0;
  102. }
  103.  
  104. void CTransferSocket::Init(const CStdString& filename, int nMode, _int64 rest)
  105. {
  106.     ASSERT(nMode == TRANSFERMODE_SEND || nMode == TRANSFERMODE_RECEIVE);
  107.     m_bReady = TRUE;
  108.     m_Filename = filename;
  109.     m_nRest = rest;
  110.     m_nMode = nMode;
  111.  
  112.     if (m_pBuffer)
  113.         delete [] m_pBuffer;
  114.     m_pBuffer = 0;
  115.     if (m_pBuffer2)
  116.         delete [] m_pBuffer2;
  117.     m_pBuffer2 = 0;
  118. }
  119.  
  120. CTransferSocket::~CTransferSocket()
  121. {
  122.     delete [] m_pBuffer;
  123.     delete [] m_pBuffer2;
  124.     if (m_hFile != INVALID_HANDLE_VALUE)
  125.     {
  126.         CloseHandle(m_hFile);
  127.         m_hFile = INVALID_HANDLE_VALUE;
  128.     }
  129.  
  130.     RemoveAllLayers();
  131.     delete m_pGssLayer;
  132.     delete m_pSslLayer;
  133.  
  134.     CPermissions::DestroyDirlisting(m_pDirListing);
  135.  
  136.     if (m_useZlib)
  137.     {
  138.         if (m_nMode == TRANSFERMODE_RECEIVE)
  139.             inflateEnd(&m_zlibStream);
  140.         else
  141.             deflateEnd(&m_zlibStream);
  142.     }
  143. }
  144.  
  145.  
  146. //Die folgenden Zeilen nicht bearbeiten. Sie werden vom Klassen-Assistenten ben÷tigt.
  147. #if 0
  148. BEGIN_MESSAGE_MAP(CTransferSocket, CAsyncSocketEx)
  149.     //{{AFX_MSG_MAP(CTransferSocket)
  150.     //}}AFX_MSG_MAP
  151. END_MESSAGE_MAP()
  152. #endif    // 0
  153.  
  154. /////////////////////////////////////////////////////////////////////////////
  155. // Member-Funktion CTransferSocket
  156.  
  157. void CTransferSocket::OnSend(int nErrorCode)
  158. {
  159.     CAsyncSocketEx::OnSend(nErrorCode);
  160.     if (nErrorCode)
  161.     {
  162.         if (m_hFile != INVALID_HANDLE_VALUE)
  163.             CloseHandle(m_hFile);
  164.         m_hFile = INVALID_HANDLE_VALUE;
  165.         EndTransfer(1);
  166.         return;
  167.     }
  168.  
  169.     if (m_nMode == TRANSFERMODE_LIST || m_nMode == TRANSFERMODE_NLST)
  170.     { //Send directory listing
  171.         if (!m_bStarted)
  172.             if (!InitTransfer(TRUE))
  173.                 return;
  174.  
  175.         if (m_useZlib)
  176.         {
  177.             if (!m_pBuffer)
  178.             {
  179.                 m_pBuffer = new char[m_nBufSize];
  180.                 m_nBufferPos = 0;
  181.  
  182.                 m_zlibStream.next_in = (Bytef *)m_pBuffer; // Make sure next_in is not 0 in all cases
  183.  
  184.                 m_zlibStream.next_out = (Bytef *)m_pBuffer;
  185.                 m_zlibStream.avail_out = m_nBufSize;
  186.             }
  187.  
  188.             while (true)
  189.             {
  190.                 int numsend;
  191.                 if (!m_zlibStream.avail_in)
  192.                 {
  193.                     if (m_pDirListing)
  194.                     {
  195.                         m_zlibStream.next_in = (Bytef *)m_pDirListing->buffer;
  196.                         m_zlibStream.avail_in = m_pDirListing->len;
  197.                     }
  198.                 }
  199.                 if (!m_zlibStream.avail_out)
  200.                 {
  201.                     if (m_nBufferPos >= m_nBufSize)
  202.                     {
  203.                         m_nBufferPos = 0;
  204.                         m_zlibStream.next_out = (Bytef *)m_pBuffer;
  205.                         m_zlibStream.avail_out = m_nBufSize;
  206.                     }
  207.                 }
  208.  
  209.                 int res = Z_OK;
  210.                 if (m_zlibStream.avail_out)
  211.                 {
  212.                     m_zlibStream.total_in = 0;
  213.                     m_zlibStream.total_out = 0;
  214.                     res = deflate(&m_zlibStream, (m_pDirListing && m_pDirListing->pNext) ? 0 : Z_FINISH);
  215.                     m_currentFileOffset += m_zlibStream.total_in;
  216.                     m_zlibBytesIn += m_zlibStream.total_in;
  217.                     m_zlibBytesOut += m_zlibStream.total_out;
  218.                     if (res == Z_STREAM_END)
  219.                     {
  220.                         if (m_pDirListing && m_pDirListing->pNext)
  221.                         {
  222.                             ShutDown();
  223.                             EndTransfer(6);
  224.                             return;
  225.                         }
  226.                         if (!(m_nBufSize - m_nBufferPos - m_zlibStream.avail_out))
  227.                             break;
  228.                     }
  229.                     else if (res != Z_OK)
  230.                     {
  231.                         ShutDown();
  232.                         EndTransfer(6);
  233.                         return;
  234.                     }
  235.                     if (!m_zlibStream.avail_in && m_pDirListing)
  236.                     {
  237.                         t_dirlisting *pPrev = m_pDirListing;
  238.                         m_pDirListing = m_pDirListing->pNext;
  239.                         delete pPrev;
  240.                     }
  241.                 }
  242.                 
  243.                 numsend = m_nBufSize;
  244.                 unsigned int len = m_nBufSize - m_nBufferPos - m_zlibStream.avail_out;
  245.                 if (!len)
  246.                     continue;
  247.  
  248.                 if (len < m_nBufSize)
  249.                     numsend = len;
  250.                 
  251.                 long long nLimit = m_pOwner->GetSpeedLimit(download);
  252.                 if (nLimit != -1 && GetState() != aborted && numsend > nLimit)
  253.                     numsend = static_cast<int>(nLimit);
  254.  
  255.                 if (!numsend)
  256.                     return;
  257.  
  258.                 int numsent = Send(m_pBuffer + m_nBufferPos, numsend);
  259.                 if (numsent == SOCKET_ERROR)
  260.                 {
  261.                     if (GetLastError() != WSAEWOULDBLOCK)
  262.                         EndTransfer(1);
  263.                     return;
  264.                 }
  265.  
  266.                 if (nLimit != -1 && GetState() != aborted)
  267.                     m_pOwner->m_SlQuotas[download].nTransferred += numsent;
  268.  
  269.                 ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
  270.                 m_wasActiveSinceCheck = true;
  271.                 m_nBufferPos += numsent;
  272.  
  273.                 if (!m_zlibStream.avail_in && !m_pDirListing && m_zlibStream.avail_out &&
  274.                     m_zlibStream.avail_out + m_nBufferPos == m_nBufSize && res == Z_STREAM_END)
  275.                 {
  276.                     break;
  277.                 }
  278.  
  279.                 //Check if there are other commands in the command queue.
  280.                 MSG msg;
  281.                 if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  282.                 {
  283.                     TriggerEvent(FD_WRITE);
  284.                     return;
  285.                 }
  286.             }
  287.         }
  288.         else
  289.         {
  290.             while (m_pDirListing && m_pDirListing->len)
  291.             {
  292.                 int numsend = m_nBufSize;
  293.                 if ((m_pDirListing->len - m_nBufferPos) < m_nBufSize)
  294.                     numsend = m_pDirListing->len - m_nBufferPos;
  295.  
  296.                 long long nLimit = m_pOwner->GetSpeedLimit(download);
  297.                 if (nLimit != -1 && GetState() != aborted && numsend > nLimit)
  298.                     numsend = static_cast<int>(nLimit);
  299.  
  300.                 if (!numsend)
  301.                     return;
  302.  
  303.                 int numsent = Send(m_pDirListing->buffer + m_nBufferPos, numsend);
  304.                 if (numsent == SOCKET_ERROR)
  305.                 {
  306.                     int error = GetLastError();
  307.                     if (error != WSAEWOULDBLOCK)
  308.                         EndTransfer(1);
  309.                     return;
  310.                 }
  311.  
  312.                 if (nLimit != -1 && GetState() != aborted)
  313.                     m_pOwner->m_SlQuotas[download].nTransferred += numsent;
  314.  
  315.                 ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
  316.                 m_wasActiveSinceCheck = true;
  317.                 if (numsent < numsend)
  318.                     m_nBufferPos += numsent;
  319.                 else
  320.                     m_nBufferPos += numsend;
  321.                 
  322.                 m_currentFileOffset += numsent;
  323.  
  324.                 ASSERT(m_nBufferPos <= m_pDirListing->len);
  325.                 if (m_nBufferPos == m_pDirListing->len)
  326.                 {
  327.                     t_dirlisting *pPrev = m_pDirListing;
  328.                     m_pDirListing = m_pDirListing->pNext;
  329.                     delete pPrev;
  330.                     m_nBufferPos = 0;
  331.     
  332.                     if (!m_pDirListing)
  333.                         break;
  334.                 }
  335.  
  336.                 //Check if there are other commands in the command queue.
  337.                 MSG msg;
  338.                 if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  339.                 {
  340.                     TriggerEvent(FD_WRITE);
  341.                     return;
  342.                 }
  343.             }
  344.         }
  345.  
  346.         if (m_waitingForSslHandshake)
  347.         {
  348.             // Don't yet issue a shutdown
  349.             return;
  350.         }
  351.  
  352.         if (m_pGssLayer || m_pSslLayer)
  353.         {
  354.             if (!ShutDown() && GetLastError() == WSAEWOULDBLOCK)
  355.                 return;
  356.         }
  357.         else
  358.             ShutDown();
  359.         EndTransfer(0);
  360.     }
  361.     else if (m_nMode == TRANSFERMODE_SEND)
  362.     { //Send file
  363.         if (!m_bStarted)
  364.             if (!InitTransfer(TRUE))
  365.                 return;
  366.         if (m_useZlib)
  367.         {
  368.             if (!m_pBuffer2)
  369.             {
  370.                 m_pBuffer2 = new char[m_nBufSize];
  371.  
  372.                 m_zlibStream.next_in = (Bytef *)m_pBuffer2;
  373.             }
  374.  
  375.             while (true)
  376.             {
  377.                 int numsend;
  378.                 if (!m_zlibStream.avail_in)
  379.                 {
  380.                     if (m_hFile != INVALID_HANDLE_VALUE)
  381.                     {
  382.                         DWORD numread;
  383.                         if (!ReadFile(m_hFile, m_pBuffer2, m_nBufSize, &numread, 0))
  384.                         {
  385.                             CloseHandle(m_hFile);
  386.                             m_hFile = INVALID_HANDLE_VALUE;
  387.                             EndTransfer(3); // TODO: Better reason
  388.                             return;
  389.                         }
  390.                         m_currentFileOffset += numread;
  391.  
  392.                         m_zlibStream.next_in = (Bytef *)m_pBuffer2;
  393.                         m_zlibStream.avail_in = numread;
  394.  
  395.                         if (numread < m_nBufSize)
  396.                         {
  397.                             CloseHandle(m_hFile);
  398.                             m_hFile = INVALID_HANDLE_VALUE;
  399.  
  400.                             if (m_waitingForSslHandshake)
  401.                                 return;
  402.                         }
  403.                     }
  404.                 }
  405.                 if (!m_zlibStream.avail_out)
  406.                 {
  407.                     if (m_nBufferPos >= m_nBufSize)
  408.                     {
  409.                         m_nBufferPos = 0;
  410.                         m_zlibStream.next_out = (Bytef *)m_pBuffer;
  411.                         m_zlibStream.avail_out = m_nBufSize;
  412.                     }
  413.                 }
  414.  
  415.                 int res = Z_OK;
  416.                 if (m_zlibStream.avail_out)
  417.                 {
  418.                     m_zlibStream.total_in = 0;
  419.                     m_zlibStream.total_out = 0;
  420.                     res = deflate(&m_zlibStream, (m_hFile != INVALID_HANDLE_VALUE) ? 0 : Z_FINISH);
  421.                     m_zlibBytesIn += m_zlibStream.total_in;
  422.                     m_zlibBytesOut += m_zlibStream.total_out;
  423.                     if (res == Z_STREAM_END)
  424.                     {
  425.                         if (m_hFile != INVALID_HANDLE_VALUE)
  426.                         {
  427.                             EndTransfer(6);
  428.                             return;
  429.                         }
  430.                         if (!(m_nBufSize - m_nBufferPos - m_zlibStream.avail_out))
  431.                             break;
  432.                     }
  433.                     else if (res != Z_OK)
  434.                     {
  435.                         EndTransfer(6);
  436.                         return;
  437.                     }
  438.                 }
  439.                     
  440.                 numsend = m_nBufSize;
  441.                 unsigned int len = m_nBufSize - m_nBufferPos - m_zlibStream.avail_out;
  442.                 if (!len)
  443.                     continue;
  444.  
  445.                 if (len < m_nBufSize)
  446.                     numsend = len;
  447.                 
  448.                 long long nLimit = m_pOwner->GetSpeedLimit(download);
  449.                 if (nLimit != -1 && GetState() != aborted && numsend > nLimit)
  450.                     numsend = static_cast<int>(nLimit);
  451.  
  452.                 if (!numsend)
  453.                     return;
  454.  
  455.                 int numsent = Send(m_pBuffer + m_nBufferPos, numsend);
  456.                 if (numsent == SOCKET_ERROR)
  457.                 {
  458.                     if (GetLastError() != WSAEWOULDBLOCK)
  459.                         EndTransfer(1);
  460.                     return;
  461.                 }
  462.  
  463.                 if (nLimit != -1 && GetState() != aborted)
  464.                     m_pOwner->m_SlQuotas[download].nTransferred += numsent;
  465.  
  466.                 ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
  467.                 m_wasActiveSinceCheck = true;
  468.                 m_nBufferPos += numsent;
  469.  
  470.                 if (!m_zlibStream.avail_in && m_hFile == INVALID_HANDLE_VALUE && m_zlibStream.avail_out &&
  471.                     m_zlibStream.avail_out + m_nBufferPos == m_nBufSize && res == Z_STREAM_END)
  472.                 {
  473.                     break;
  474.                 }
  475.  
  476.                 //Check if there are other commands in the command queue.
  477.                 MSG msg;
  478.                 if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  479.                 {
  480.                     TriggerEvent(FD_WRITE);
  481.                     return;
  482.                 }
  483.             }
  484.         }
  485.         else
  486.         {
  487.             while (m_hFile != INVALID_HANDLE_VALUE || m_nBufferPos)
  488.             {
  489.                 DWORD numread;
  490.                 if (m_nBufSize - m_nBufferPos && m_hFile != INVALID_HANDLE_VALUE)
  491.                 {
  492.                     if (!ReadFile(m_hFile, m_pBuffer+m_nBufferPos, m_nBufSize-m_nBufferPos, &numread, 0))
  493.                     {
  494.                         CloseHandle(m_hFile);
  495.                         m_hFile = INVALID_HANDLE_VALUE;
  496.                         EndTransfer(3); //TODO: Better reason
  497.                         return;
  498.                     }
  499.  
  500.                     if (!numread)
  501.                     {
  502.                         CloseHandle(m_hFile);
  503.                         m_hFile = INVALID_HANDLE_VALUE;
  504.  
  505.                         if (!m_nBufferPos)
  506.                         {
  507.                             if (m_waitingForSslHandshake)
  508.                                 return;
  509.  
  510.                             if (m_pGssLayer || m_pSslLayer)
  511.                                 if (!ShutDown() && GetLastError() == WSAEWOULDBLOCK)
  512.                                     return;
  513.                             EndTransfer(0);
  514.                             return;
  515.                         }
  516.                     }
  517.                     else
  518.                         m_currentFileOffset += numread;
  519.  
  520.                     numread += m_nBufferPos;
  521.                     m_nBufferPos = 0;
  522.                 }
  523.                 else
  524.                     numread = m_nBufferPos;
  525.                 m_nBufferPos = 0;
  526.  
  527.                 if (numread < m_nBufSize)
  528.                 {
  529.                     CloseHandle(m_hFile);
  530.                     m_hFile = INVALID_HANDLE_VALUE;
  531.                 }
  532.  
  533.                 int numsend = numread;
  534.                 long long nLimit = m_pOwner->GetSpeedLimit(download);
  535.                 if (nLimit != -1 && GetState() != aborted && numsend > nLimit)
  536.                     numsend = static_cast<int>(nLimit);
  537.  
  538.                 if (!numsend)
  539.                 {
  540.                     m_nBufferPos = numread;
  541.                     return;
  542.                 }
  543.  
  544.                 int    numsent = Send(m_pBuffer, numsend);
  545.                 if (numsent==SOCKET_ERROR)
  546.                 {
  547.                     if (GetLastError()!=WSAEWOULDBLOCK)
  548.                     {
  549.                         CloseHandle(m_hFile);
  550.                         m_hFile = INVALID_HANDLE_VALUE;
  551.                         EndTransfer(1);
  552.                         return;
  553.                     }
  554.                     m_nBufferPos=numread;
  555.                     return;
  556.                 }
  557.                 else if ((unsigned int)numsent<numread)
  558.                 {
  559.                     memmove(m_pBuffer, m_pBuffer+numsent, numread-numsent);
  560.                     m_nBufferPos=numread-numsent;
  561.                 }
  562.  
  563.                 if (nLimit != -1 && GetState() != aborted)
  564.                     m_pOwner->m_SlQuotas[download].nTransferred += numsent;
  565.     
  566.                 ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
  567.                 m_wasActiveSinceCheck = true;
  568.  
  569.                 //Check if there are other commands in the command queue.
  570.                 MSG msg;
  571.                 if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  572.                 {
  573.                     TriggerEvent(FD_WRITE);
  574.                     return;
  575.                 }
  576.             }
  577.         }
  578.  
  579.         if (m_waitingForSslHandshake)
  580.         {
  581.             // Don't yet issue a shutdown
  582.             return;
  583.         }
  584.  
  585.         if (m_pGssLayer || m_pSslLayer)
  586.         {
  587.             if (!ShutDown() && GetLastError() == WSAEWOULDBLOCK)
  588.                 return;
  589.         }
  590.         else
  591.             ShutDown();
  592.         Sleep(0); //Give the system the possibility to relay the data
  593.                   //If not using Sleep(0), GetRight for example can't receive the last chunk.
  594.         EndTransfer(0);
  595.     }
  596.     else if (m_nMode == TRANSFERMODE_NOTSET)
  597.     {
  598.         m_premature_send = true;
  599.     }
  600. }
  601.  
  602. void CTransferSocket::OnConnect(int nErrorCode)
  603. {
  604.     if (nErrorCode)
  605.     {
  606.         if (m_hFile!=INVALID_HANDLE_VALUE)
  607.         {
  608.             CloseHandle(m_hFile);
  609.             m_hFile = INVALID_HANDLE_VALUE;
  610.         }
  611.         EndTransfer(2);
  612.         return;
  613.     }
  614.  
  615.     int size = (int)m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_BUFFERSIZE2);
  616.     if (size > 0)
  617.     {
  618.         if (m_nMode == TRANSFERMODE_RECEIVE)
  619.             SetSockOpt(SO_RCVBUF, &size, sizeof(int));
  620.         else
  621.             SetSockOpt(SO_SNDBUF, &size, sizeof(int));
  622.     }
  623.  
  624.     if (m_pGssLayer)
  625.         VERIFY(AddLayer(m_pGssLayer));
  626.     if (m_sslContext)
  627.     {
  628.         if (!m_pSslLayer)
  629.             m_pSslLayer = new CAsyncSslSocketLayer();
  630.         VERIFY(AddLayer(m_pSslLayer));
  631.  
  632.         int code = m_pSslLayer->InitSSLConnection(false, m_sslContext);
  633.         if (code == SSL_FAILURE_LOADDLLS)
  634.             m_pOwner->SendStatus(_T("Failed to load SSL libraries"), 1);
  635.         else if (code == SSL_FAILURE_INITSSL)
  636.             m_pOwner->SendStatus(_T("Failed to initialize SSL library"), 1);
  637.         
  638.         if (code)
  639.         {
  640.             EndTransfer(2);
  641.             return;
  642.         }
  643.         m_waitingForSslHandshake = true;
  644.     }
  645.  
  646.     if (!m_bStarted)
  647.         InitTransfer(FALSE);
  648.  
  649.     CAsyncSocketEx::OnConnect(nErrorCode);
  650. }
  651.  
  652. void CTransferSocket::OnClose(int nErrorCode)
  653. {
  654.     if (nErrorCode)
  655.     {
  656.         if (m_hFile)
  657.         {
  658.             FlushFileBuffers(m_hFile);
  659.             CloseHandle(m_hFile);
  660.             m_hFile = INVALID_HANDLE_VALUE;
  661.         }
  662.         EndTransfer(1);
  663.         return;
  664.     }
  665.     if (m_bReady)
  666.     {
  667.         if (m_nMode==TRANSFERMODE_RECEIVE)
  668.         {
  669.             //Receive all data still waiting to be recieve
  670.             _int64 pos=0;
  671.             do
  672.             {
  673.                 if (m_hFile != INVALID_HANDLE_VALUE)
  674.                     pos=GetPosition64(m_hFile);
  675.                 OnReceive(0);
  676.                 if (m_hFile != INVALID_HANDLE_VALUE)
  677.                     if (pos == GetPosition64(m_hFile))
  678.                         break; //Leave loop when no data was written to file
  679.             } while (m_hFile != INVALID_HANDLE_VALUE); //Or file was closed
  680.             if (m_hFile != INVALID_HANDLE_VALUE)
  681.             {
  682.                 FlushFileBuffers(m_hFile);
  683.                 CloseHandle(m_hFile);
  684.                 m_hFile = INVALID_HANDLE_VALUE;
  685.             }
  686.             EndTransfer(0);
  687.         }
  688.         else
  689.             EndTransfer((m_nMode == TRANSFERMODE_RECEIVE) ? 0 : 1);
  690.     }
  691.  
  692.     CAsyncSocketEx::OnClose(nErrorCode);
  693. }
  694.  
  695. int CTransferSocket::GetStatus()
  696. {
  697.     return m_status;
  698. }
  699.  
  700. void CTransferSocket::OnAccept(int nErrorCode)
  701. {
  702.     CAsyncSocketEx tmp;
  703.     Accept(tmp);
  704.     SOCKET socket=tmp.Detach();
  705.     Close();
  706.     Attach(socket);
  707.     m_bAccepted = TRUE;
  708.  
  709.     int size = (int)m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_BUFFERSIZE2);
  710.     if (size > 0)
  711.     {
  712.         if (m_nMode == TRANSFERMODE_RECEIVE)
  713.             SetSockOpt(SO_RCVBUF, &size, sizeof(int));
  714.         else
  715.             SetSockOpt(SO_SNDBUF, &size, sizeof(int));
  716.     }
  717.  
  718.     if (m_pGssLayer)
  719.         VERIFY(AddLayer(m_pGssLayer));
  720.     if (m_sslContext)
  721.     {
  722.         if (!m_pSslLayer)
  723.             m_pSslLayer = new CAsyncSslSocketLayer();
  724.         VERIFY(AddLayer(m_pSslLayer));
  725.         
  726.         int code = m_pSslLayer->InitSSLConnection(false, m_sslContext);
  727.         if (code == SSL_FAILURE_LOADDLLS)
  728.             m_pOwner->SendStatus(_T("Failed to load SSL libraries"), 1);
  729.         else if (code == SSL_FAILURE_INITSSL)
  730.             m_pOwner->SendStatus(_T("Failed to initialize SSL library"), 1);
  731.         
  732.         if (code)
  733.         {
  734.             EndTransfer(2);
  735.             return;
  736.         }
  737.         m_waitingForSslHandshake = true;
  738.     }
  739.  
  740.     if (m_bReady)
  741.         if (!m_bStarted)
  742.             InitTransfer(FALSE);
  743.  
  744.     CAsyncSocketEx::OnAccept(nErrorCode);
  745. }
  746.  
  747. void CTransferSocket::OnReceive(int nErrorCode)
  748. {
  749.     CAsyncSocketEx::OnReceive(nErrorCode);
  750.  
  751.     bool obeySpeedLimit = true;
  752.     if (nErrorCode == WSAESHUTDOWN)
  753.         obeySpeedLimit = false;
  754.     else if (nErrorCode)
  755.     {
  756.         if (m_hFile != INVALID_HANDLE_VALUE)
  757.         {
  758.             CloseHandle(m_hFile);
  759.             m_hFile = INVALID_HANDLE_VALUE;
  760.         }
  761.         EndTransfer(3);
  762.         return;
  763.     }
  764.     else if (GetState() == closed)
  765.         obeySpeedLimit = false;
  766.  
  767.     if (m_nMode == TRANSFERMODE_RECEIVE)
  768.     {
  769.         if (!m_bStarted)
  770.             if (!InitTransfer(FALSE))
  771.                 return;
  772.  
  773.         m_wasActiveSinceCheck = true;
  774.  
  775.         int len = m_nBufSize;
  776.         long long nLimit = -1;
  777.         if (obeySpeedLimit)
  778.         {
  779.             nLimit = m_pOwner->GetSpeedLimit(upload);
  780.             if (nLimit != -1 && GetState() != aborted && len > nLimit)
  781.                 len = static_cast<int>(nLimit);
  782.         }
  783.  
  784.         if (!len)
  785.             return;
  786.  
  787.         int numread = Receive(m_pBuffer, len);
  788.  
  789.         if (numread == SOCKET_ERROR)
  790.         {
  791.             const int error = GetLastError();
  792.             if (m_pSslLayer && error == WSAESHUTDOWN)
  793.             {
  794.                 // Don't do anything at this point, we should get OnClose soon
  795.                 return;
  796.             }
  797.             else if (error != WSAEWOULDBLOCK)
  798.             {
  799.                 if (m_hFile!=INVALID_HANDLE_VALUE)
  800.                 {
  801.                     CloseHandle(m_hFile);
  802.                     m_hFile = INVALID_HANDLE_VALUE;
  803.                 }
  804.                 EndTransfer(1);
  805.             }
  806.             return;
  807.         }
  808.         if (!numread)
  809.         {
  810.             if (m_hFile != INVALID_HANDLE_VALUE)
  811.             {
  812.                 CloseHandle(m_hFile);
  813.                 m_hFile = INVALID_HANDLE_VALUE;
  814.             }
  815.             EndTransfer(0);
  816.             return;
  817.         }
  818.         ((CServerThread *)m_pOwner->m_pOwner)->IncRecvCount(numread);
  819.  
  820.         if (nLimit != -1 && GetState() != aborted)
  821.             m_pOwner->m_SlQuotas[upload].nTransferred += numread;
  822.  
  823.         if (m_useZlib)
  824.         {
  825.             if (!m_pBuffer2)
  826.                 m_pBuffer2 = new char[m_nBufSize];
  827.  
  828.             m_zlibStream.next_in = (Bytef *)m_pBuffer;
  829.             m_zlibStream.avail_in = numread;
  830.             m_zlibStream.next_out = (Bytef *)m_pBuffer2;
  831.             m_zlibStream.avail_out = m_nBufSize;
  832.             
  833.             m_zlibStream.total_in = 0;
  834.             m_zlibStream.total_out = 0;
  835.             int res = inflate(&m_zlibStream, 0);
  836.             m_zlibBytesIn += m_zlibStream.total_in;
  837.             m_zlibBytesOut += m_zlibStream.total_out;
  838.             
  839.             while (res == Z_OK)
  840.             {
  841.                 DWORD numwritten;
  842.                 if (!WriteFile(m_hFile, m_pBuffer2, m_nBufSize - m_zlibStream.avail_out, &numwritten, 0) || numwritten != m_nBufSize - m_zlibStream.avail_out)
  843.                 {
  844.                     CloseHandle(m_hFile);
  845.                     m_hFile = INVALID_HANDLE_VALUE;
  846.                     EndTransfer(3); // TODO: Better reason
  847.                     return;
  848.                 }
  849.                 m_currentFileOffset += numwritten;
  850.  
  851.                 m_zlibStream.next_out = (Bytef *)m_pBuffer2;
  852.                 m_zlibStream.avail_out = m_nBufSize;
  853.                 res = inflate(&m_zlibStream, 0);
  854.             }
  855.             if (res == Z_STREAM_END)
  856.             {
  857.                 DWORD numwritten;
  858.                 if (!WriteFile(m_hFile, m_pBuffer2, m_nBufSize - m_zlibStream.avail_out, &numwritten, 0) || numwritten != m_nBufSize - m_zlibStream.avail_out)
  859.                 {
  860.                     CloseHandle(m_hFile);
  861.                     m_hFile = INVALID_HANDLE_VALUE;
  862.                     EndTransfer(3); // TODO: Better reason
  863.                     return;
  864.                 }
  865.                 m_currentFileOffset += numwritten;
  866.             }
  867.             else if (res != Z_OK && res != Z_BUF_ERROR)
  868.             {
  869.                 CloseHandle(m_hFile);
  870.                 m_hFile = INVALID_HANDLE_VALUE;
  871.                 EndTransfer(6);
  872.                 return;
  873.             }
  874.         }
  875.         else
  876.         {
  877.             DWORD numwritten;
  878.             if (!WriteFile(m_hFile, m_pBuffer, numread, &numwritten, 0) || numwritten!=(unsigned int)numread)
  879.             {
  880.                 CloseHandle(m_hFile);
  881.                 m_hFile = INVALID_HANDLE_VALUE;
  882.                 EndTransfer(3); //TODO: Better reason
  883.                 return;
  884.             }
  885.             m_currentFileOffset += numwritten;
  886.         }
  887.     }
  888. }
  889.  
  890. void CTransferSocket::PasvTransfer()
  891. {
  892.     if (m_bAccepted)
  893.         if (!m_bStarted)
  894.             InitTransfer(FALSE);
  895.     if (m_premature_send)
  896.     {
  897.         m_premature_send = false;
  898.         OnSend(0);
  899.     }
  900. }
  901.  
  902. BOOL CTransferSocket::InitTransfer(BOOL bCalledFromSend)
  903. {
  904.     int optAllowServerToServer, optStrictFilter;
  905.  
  906.     if (m_nMode == TRANSFERMODE_RECEIVE)
  907.     {
  908.         optAllowServerToServer = OPTION_INFXP;
  909.         optStrictFilter = OPTION_NOINFXPSTRICT;
  910.     }
  911.     else
  912.     {
  913.         optAllowServerToServer = OPTION_OUTFXP;
  914.         optStrictFilter = OPTION_NOOUTFXPSTRICT;
  915.     }
  916.  
  917.     if (!m_pOwner->m_pOwner->m_pOptions->GetOptionVal(optAllowServerToServer))
  918.     { //Check if the IP of the remote machine is valid
  919.         CStdString OwnerIP, TransferIP;
  920.         UINT port = 0;
  921.  
  922.         SOCKADDR_IN sockAddr;
  923.         memset(&sockAddr, 0, sizeof(sockAddr));
  924.         int nSockAddrLen = sizeof(sockAddr);
  925.         if (!m_pOwner->GetSockName(OwnerIP, port))
  926.         {
  927.             EndTransfer(5);
  928.             return FALSE;
  929.         }
  930.  
  931.         if (!GetSockName(TransferIP, port))
  932.         {
  933.             EndTransfer(5);
  934.             return FALSE;
  935.         }
  936.  
  937.         if (!IsLocalhost(OwnerIP) && !IsLocalhost(TransferIP))
  938.         {
  939.             
  940.             if (GetFamily() == AF_INET6)
  941.             {
  942.                 OwnerIP = GetIPV6LongForm(OwnerIP);
  943.                 TransferIP = GetIPV6LongForm(TransferIP);
  944.             }
  945.             
  946.             if (!m_pOwner->m_pOwner->m_pOptions->GetOptionVal(optStrictFilter))
  947.             {
  948.                 if (GetFamily() == AF_INET6)
  949.                 {
  950.                     // Assume a /64
  951.                     OwnerIP = OwnerIP.Left(20);
  952.                     TransferIP = TransferIP.Left(20);
  953.                 }
  954.                 else
  955.                 {
  956.                     // Assume a /24
  957.                     OwnerIP = OwnerIP.Left(OwnerIP.ReverseFind('.'));
  958.                     TransferIP = TransferIP.Left(TransferIP.ReverseFind('.'));
  959.                 }
  960.             }
  961.  
  962.             if (OwnerIP != TransferIP)
  963.             {
  964.                 EndTransfer(5);
  965.                 return FALSE;
  966.             }
  967.         }
  968.     }
  969.  
  970.     if (m_nMode == TRANSFERMODE_RECEIVE)
  971.         AsyncSelect(FD_READ|FD_CLOSE);
  972.     else
  973.         AsyncSelect(FD_WRITE|FD_CLOSE);
  974.     
  975.     if (m_bAccepted)
  976.     {
  977.         CStdString str = _T("150 Connection accepted");
  978.         if (m_nRest)
  979.             str.Format(_T("150 Connection accepted, restarting at offset %I64d"), m_nRest);
  980.         m_pOwner->Send(str);
  981.     }
  982.  
  983.     m_bStarted = TRUE;
  984.     if (m_nMode == TRANSFERMODE_SEND)
  985.     {
  986.         ASSERT(m_Filename != _T(""));
  987.         int shareMode = FILE_SHARE_READ;
  988.         if (m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_SHAREDWRITE))
  989.             shareMode |= FILE_SHARE_WRITE;
  990.         m_hFile = CreateFile(m_Filename, GENERIC_READ, shareMode, 0, OPEN_EXISTING, 0, 0);
  991.         if (m_hFile == INVALID_HANDLE_VALUE)
  992.         {
  993.             EndTransfer(3);
  994.             return FALSE;
  995.         }
  996.         DWORD low=(DWORD)(m_nRest&0xFFFFFFFF);
  997.         LONG high=(LONG)(m_nRest>>32);
  998.         if ((low = SetFilePointer(m_hFile, low, &high, FILE_BEGIN)) == 0xFFFFFFFF && GetLastError() != NO_ERROR)
  999.         {
  1000.             high = 0;
  1001.             low = SetFilePointer(m_hFile, 0, &high, FILE_END);
  1002.             if (low == 0xFFFFFFFF && GetLastError() != NO_ERROR)
  1003.             {
  1004.                 EndTransfer(3);
  1005.                 return FALSE;
  1006.             }
  1007.         }
  1008.         m_currentFileOffset = (((__int64)high) << 32) + low;
  1009.  
  1010.         if (!m_pBuffer)
  1011.         {
  1012.             m_pBuffer = new char[m_nBufSize];
  1013.             m_nBufferPos = 0;
  1014.  
  1015.             if (m_useZlib)
  1016.             {
  1017.                 m_zlibStream.next_out = (Bytef *)m_pBuffer;
  1018.                 m_zlibStream.avail_out = m_nBufSize;
  1019.             }
  1020.         }
  1021.     }
  1022.     else if (m_nMode == TRANSFERMODE_RECEIVE)
  1023.     {
  1024.         unsigned int buflen = 0;
  1025.         int varlen = sizeof(buflen);
  1026.         if (GetSockOpt(SO_RCVBUF, &buflen, &varlen))
  1027.         {
  1028.             if (buflen < m_nBufSize)
  1029.             {
  1030.                 buflen = m_nBufSize;
  1031.                 SetSockOpt(SO_RCVBUF, &buflen, varlen);
  1032.             }
  1033.         }
  1034.  
  1035.         if (m_hFile == INVALID_HANDLE_VALUE)
  1036.         {
  1037.             ASSERT(m_Filename != _T(""));
  1038.             int shareMode = FILE_SHARE_READ;
  1039.             if (m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_SHAREDWRITE))
  1040.                 shareMode |= FILE_SHARE_WRITE;
  1041.             m_hFile = CreateFile(m_Filename, GENERIC_WRITE, shareMode, 0, OPEN_ALWAYS, 0, 0);
  1042.             if (m_hFile == INVALID_HANDLE_VALUE)
  1043.             {
  1044.                 EndTransfer(3);
  1045.                 return FALSE;
  1046.             }
  1047.             DWORD low = (DWORD)(m_nRest&0xFFFFFFFF);
  1048.             LONG high = (LONG)(m_nRest>>32);
  1049.             low = SetFilePointer(m_hFile, low, &high, FILE_BEGIN);
  1050.             if (low == 0xFFFFFFFF && GetLastError() != NO_ERROR)
  1051.             {
  1052.                 EndTransfer(3);
  1053.                 return FALSE;
  1054.             }
  1055.             SetEndOfFile(m_hFile);
  1056.             m_currentFileOffset = (((__int64)high) << 32) + low;
  1057.         }
  1058.  
  1059.         if (!m_pBuffer)
  1060.             m_pBuffer = new char[m_nBufSize];
  1061.     }
  1062.  
  1063.     GetSystemTime(&m_LastActiveTime);
  1064.     return TRUE;
  1065. }
  1066.  
  1067. BOOL CTransferSocket::CheckForTimeout()
  1068. {
  1069.     if (!m_bReady)
  1070.         return FALSE;
  1071.  
  1072.     _int64 timeout = m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_TIMEOUT);
  1073.  
  1074.     SYSTEMTIME sCurrentTime;
  1075.     GetSystemTime(&sCurrentTime);
  1076.     FILETIME fCurrentTime;
  1077.     SystemTimeToFileTime(&sCurrentTime, &fCurrentTime);
  1078.     FILETIME fLastTime;
  1079.     if (m_wasActiveSinceCheck)
  1080.     {
  1081.         m_wasActiveSinceCheck = false;
  1082.         GetSystemTime(&m_LastActiveTime);
  1083.         return TRUE;
  1084.     }
  1085.  
  1086.     SystemTimeToFileTime(&m_LastActiveTime, &fLastTime);
  1087.     _int64 elapsed = ((_int64)(fCurrentTime.dwHighDateTime - fLastTime.dwHighDateTime) << 32) + fCurrentTime.dwLowDateTime - fLastTime.dwLowDateTime;
  1088.     if (timeout && elapsed > (timeout*10000000))
  1089.     {
  1090.         EndTransfer(4);
  1091.         return TRUE;
  1092.     }
  1093.     else if (!m_bStarted && elapsed > (10 * 10000000))
  1094.     {
  1095.         EndTransfer(2);
  1096.         return TRUE;
  1097.     }
  1098.     else if (!timeout)
  1099.         return FALSE;
  1100.  
  1101.     return TRUE;
  1102. }
  1103.  
  1104. BOOL CTransferSocket::Started() const
  1105. {
  1106.     return m_bStarted;
  1107. }
  1108.  
  1109. int CTransferSocket::GetMode() const
  1110. {
  1111.     return m_nMode;
  1112. }
  1113.  
  1114. void CTransferSocket::UseGSS(CAsyncGssSocketLayer *pGssLayer)
  1115. {
  1116.     m_pGssLayer = new CAsyncGssSocketLayer;
  1117.     m_pGssLayer->InitTransferChannel(pGssLayer);
  1118. }
  1119.  
  1120. bool CTransferSocket::UseSSL(void* sslContext)
  1121. {
  1122.     if (m_pSslLayer)
  1123.         return false;
  1124.  
  1125.     m_sslContext = sslContext;
  1126.  
  1127.     return true;
  1128. }
  1129.  
  1130. int CTransferSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
  1131. {
  1132.     for (std::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
  1133.     {
  1134.         if (m_pGssLayer && iter->pLayer == m_pGssLayer)
  1135.         {
  1136.             if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == GSS_SHUTDOWN_COMPLETE)
  1137.             {
  1138.                 Sleep(0); //Give the system the possibility to relay the data
  1139.                 //If not using Sleep(0), GetRight for example can't receive the last chunk.
  1140.                 EndTransfer(0);
  1141.  
  1142.                 do
  1143.                 {
  1144.                     delete [] iter->str;
  1145.                     iter++;
  1146.                 } while (iter != callbacks.end());
  1147.  
  1148.                 return 0;
  1149.             }
  1150.         }
  1151.         else if (m_pSslLayer && iter->pLayer == m_pSslLayer)
  1152.         {
  1153.             if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == SSL_INFO && iter->nParam2 == SSL_INFO_SHUTDOWNCOMPLETE)
  1154.             {
  1155.                 Sleep(0); //Give the system the possibility to relay the data
  1156.                 //If not using Sleep(0), GetRight for example can't receive the last chunk.
  1157.                 EndTransfer(0);
  1158.  
  1159.                 do
  1160.                 {
  1161.                     delete [] iter->str;
  1162.                     iter++;
  1163.                 } while (iter != callbacks.end());
  1164.                 
  1165.                 return 0;
  1166.             }
  1167.             else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == SSL_VERBOSE_WARNING)
  1168.             {
  1169.                 if (iter->str)
  1170.                 {
  1171.                     CStdString str = "Data connection SSL warning: ";
  1172.                     str += iter->str;
  1173.  
  1174.                     m_pOwner->SendStatus(str, 1);
  1175.                 }
  1176.             }
  1177.             /* Verbose info for debugging
  1178.             else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == SSL_VERBOSE_INFO)
  1179.             {
  1180.                 if (iter->str)
  1181.                 {
  1182.                     CStdString str = "SSL info: ";
  1183.                     str += iter->str;
  1184.  
  1185.                     m_pOwner->SendStatus(str, 0);
  1186.                 }
  1187.             }*/
  1188.             else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == SSL_INFO_ESTABLISHED)
  1189.             {
  1190.                 delete [] iter->str;
  1191.                 m_waitingForSslHandshake = false;
  1192.                 m_pOwner->SendStatus(_T("SSL connection for data connection established"), 0);
  1193.                 return 0;
  1194.             }
  1195.         }
  1196.         delete [] iter->str;
  1197.     }
  1198.     return 0;
  1199. }
  1200.  
  1201. bool CTransferSocket::InitZLib(int level)
  1202. {
  1203.     int res;
  1204.     if (m_nMode == TRANSFERMODE_RECEIVE)
  1205.         res = inflateInit2(&m_zlibStream, 15);
  1206.     else
  1207.         res = deflateInit2(&m_zlibStream, level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
  1208.     
  1209.     if (res == Z_OK)
  1210.         m_useZlib = true;
  1211.  
  1212.     return res == Z_OK;
  1213. }
  1214.  
  1215. bool CTransferSocket::GetZlibStats(_int64 &bytesIn, _int64 &bytesOut) const
  1216. {
  1217.     bytesIn = m_zlibBytesIn;
  1218.     bytesOut = m_zlibBytesOut;
  1219.     
  1220.     return true;
  1221. }
  1222.  
  1223. void CTransferSocket::EndTransfer(int status)
  1224. {
  1225.     Close();
  1226.  
  1227.     if (m_bSentClose)
  1228.         return;
  1229.  
  1230.     m_bSentClose = TRUE;
  1231.     m_status = status;
  1232.     m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1233. }
  1234.